/* This module provides generic functions to deal with linked list */

#ifndef LINKED_LIST_H
#define LINKED_LIST_H

#include "error_codes.h"
#include "null.h"
#include "system_id.h"
#include "types.h"
#include "dynamic_memory.h"

/* type definition */
typedef struct _link{
  void* data;
  struct _link* next;
}link;

typedef link* list;

/* Adds new at the head of l. Returns SUCCESS in case of success, OUT_OF_MEMORY otherwise. */
int32_t linked_list_add(list* l, void* new);

/* Adds new at the end of list. Returns SUCCESS or OUT_OF_MEMORY */
int32_t linked_list_add_tail(list* l, void* new);

/* Adds new after prev. Returns SUCCESS in case of success, OUT_OF_MEMORY otherwise */
int32_t linked_list_add_after_prev(list* l, list prev, void* new);

/* Deletes target from l. Uses the function compare to know whether the correct element has been found. compare must take two pointers as arguments and returns a boolean result. It also uses the function free_data to know how to free a link's payload. free_data takes one pointer as parameter and returns a boolean result, indicating if the free worked or not. Returns SUCCESS in case of success, FAILURE otherwise. */
int32_t linked_list_delete(list* l, void* target, int32_t (*compare)(void*, void*), int32_t (*free_data)(void*));

/* deletes target from l. It also uses the function free_data to know how to free a link's payload. free_data takes one pointer as parameter and returns a boolean result, indicating if the free worked or not. Returns SUCCESS in case of success, FAILURE otherwise.*/
int32_t linked_list_delete_after_prev(list* l, list prev, list target,int32_t (*free_data)(void*));

/* returns the number of elements in list */
int32_t count_list(list l);

#endif
